package kaka.rpc
{
	/**
	 * 请求响应抽象基类
	 * @author kaka
	 */
	 
	public class AbstractResponder implements IInvokeResponder
	{
		private var resultLiteners:Array;
		private var faultListener:Array;
		private var _defaultHandler:Function;
		/**
		 * 仅当用户没有指定任何回调函数时启用
		 * @param defaultHandler
		 */
		public function AbstractResponder(defaultHandler:Function=null)
		{
			_defaultHandler=defaultHandler;
		}
		/**
		 * 添加请求处理成功回调函数,可传入多个参数
		 * @param handler 请求成功回调函数
		 * @param params 请求参数
		 */
		public function addResultListener(handler:Function, ...params):IInvokeResponder
		{
			if(!resultLiteners)
			{
				resultLiteners=new Array();
			}
			resultLiteners.push(new Listener(handler,params));
			return this;
		}
		public function addFaultListener(handler:Function, ...params):IInvokeResponder
		{
			if(!faultListener)
			{
				faultListener=new Array();
			}
			faultListener.push(new Listener(handler,params));
			return this;
		}
		protected function notifyResultListener(result:Object,first:int=0):void
		{
			if(resultLiteners)
			{
				for(var i:int=first;i<resultLiteners.length;i++)
				{
					var listener:Listener=resultLiteners[i];
					var fun:Function=listener.handler;
					var params:Array=listener.arguments;
					params.unshift(result);
					fun.apply(null,params);
				}
			}
		}
		protected function notifyFaultListener(fault:Object,first:int=0):void
		{
			if(faultListener)
			{
				for(var i:int=first;i<faultListener.length;i++)
				{
					var listener:Listener=faultListener[i];
					var fun:Function=listener.handler;
					var params:Array=listener.arguments;
					params.unshift(fault);
					fun.apply(null,params);
				}
			}
			else if(_defaultHandler==null)
			{
				_defaultHandler.apply(null,[fault]);
			}
		}
		protected function clear():void
		{
			resultLiteners=[];
			faultListener=[];
		}
	}
}
class Listener
{
	private var _handler:Function;
	private var _args:Array;
	/**
	 * 储存回调函数和回调参数
	 * @param handler
	 * @param args
	 */
	public function Listener(handler:Function,args:Array)
	{
		this._handler=handler;
		this._args=args;
	}
	public function get handler():Function
	{
		return _handler;
	}
	public function get arguments():Array
	{
		return _args.concat();
	}
}